package com.sanuo.pico.act.work;

import android.os.Bundle;
import android.view.View;

import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.menu.app.MyApp;
import com.menu.app.activity.BaseBoardActivity;
import com.menu.app.db.CusUsageDao;
import com.menu.app.db.CustomDao;
import com.menu.app.db.DBListener;
import com.menu.app.db.DocDao;
import com.menu.app.db.TreatDao;
import com.menu.app.db.bean.Custom;
import com.menu.app.db.bean.Treat;
import com.menu.app.http.bean.ReportBean;
import com.menu.app.http.req.ReportReq;
import com.menu.app.it.ReqCallback;
import com.menu.app.model.Models;
import com.menu.app.util.Utils;
import com.sanuo.pico.App;
import com.sanuo.pico.BuildConfig;
import com.sanuo.pico.bean.WorkParam;
import com.sanuo.pico.databinding.ActWorkBinding;
import com.sanuo.pico.event.ConditionState;
import com.sanuo.pico.event.CountEvent;
import com.sanuo.pico.event.Energy;
import com.sanuo.pico.event.EnergyDensity;
import com.sanuo.pico.event.Event;
import com.sanuo.pico.event.HandleConnect;
import com.sanuo.pico.event.LengthEvent;
import com.sanuo.pico.event.LightEvent;
import com.sanuo.pico.event.LoadingEvent;
import com.sanuo.pico.event.P2Event;
import com.sanuo.pico.event.ReadyState;
import com.sanuo.pico.event.ShowLength;
import com.sanuo.pico.event.TipEvent;
import com.sanuo.pico.event.VbEvent;
import com.sanuo.pico.it.WorkingPage;
import com.sanuo.pico.utils.Command;
import com.sanuo.pico.utils.Const;
import com.sanuo.pico.view.ArcSeekBar;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WorkAct extends BaseWorkActivity implements WorkingPage {

    ActWorkBinding binding;
    List<View> lights = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActWorkBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        binding.p1.value.setVisibility(View.GONE);
        binding.p2.value.setVisibility(View.GONE);

        binding.back.setOnClickListener(v -> {
            Command.sendTouchEvent(0, 0x20);
            if (Const.jump && !isWorking()) {
                finish();
            }
        });
        binding.on.setOnClickListener(v -> {
            boolean bo = !binding.on.isSelected();
            if (bo) {
                binding.lights.setVisibility(View.VISIBLE);
            } else {
                binding.lights.setVisibility(View.GONE);
            }
            binding.on.setSelected(bo);
        });

        lights.add(binding.off);
        lights.add(binding.r1);
        lights.add(binding.r2);
        lights.add(binding.r3);
        lights.add(binding.r4);
        lights.add(binding.r5);
        for (int i = 0; i < lights.size(); i++) {
            final int j = i;
            lights.get(i).setOnClickListener(v -> changeLight(j));
        }

        binding.num.setOnClickListener(v -> Command.sendTouchEvent(0, 0x31));
        binding.count.setOnClickListener(v -> Command.sendTouchEvent(0, 0x32));

        binding.simmer.setOnClickListener(v -> {
            Command.sendTouchEvent(0, 0x3b);
            if (Const.work) {
                int i = Event.condition.getValue();
                Event.condition.postValue(i == 0 ? 1 : 0);
            }
        });
        binding.work.setOnClickListener(v -> {
            Command.sendTouchEvent(0, 0x3c);
            if (Const.work) {
                int i = Event.ready.getValue();
                Event.ready.postValue(i == 0 ? 1 : 0);
            }
        });

        binding.f0.setOnClickListener(v -> Command.sendTouchEvent(0, 0x39));
        binding.f1.setOnClickListener(v -> Command.sendTouchEvent(0, 0x3a));

        setTouch(binding.p1.down, () -> Command.sendTouchEvent(54));
        setTouch(binding.p1.up, () -> Command.sendTouchEvent(53));

        setTouch(binding.p2.down, () -> Command.sendTouchEvent(56));
        setTouch(binding.p2.up, () -> Command.sendTouchEvent(55));

        binding.seek1.setOnProgressChangeListener(new ArcSeekBar.OnProgressChangeListener() {
            @Override
            public void onProgressChanged(ArcSeekBar seekBar, int progress, boolean isUser) {
                if (isUser) {
                    Event.energy.postValue(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(ArcSeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(ArcSeekBar seekBar) {
                Command.setParam(Event.energy.getValue(), Event.p2.getValue(), Event.light.getValue());
            }
        });

        binding.seek2.setOnProgressChangeListener(new ArcSeekBar.OnProgressChangeListener() {
            @Override
            public void onProgressChanged(ArcSeekBar seekBar, int progress, boolean isUser) {
                if (isUser) {
                    if (Event.vb.is585Or650()) {
                        if (Event.p2.getValue() != 1) {
                            Event.p2.postValue(1);
                        } else {
                            binding.seek2.setProgress(1);
                        }
                    } else {
                        Event.p2.postValue(progress);
                    }
                }
            }

            @Override
            public void onStartTrackingTouch(ArcSeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(ArcSeekBar seekBar) {
                Command.setParam(Event.energy.getValue(), Event.p2.getValue(), Event.light.getValue());
            }
        });

        onMessageEvent(Event.count);
        onMessageEvent(Event.condition);
        onMessageEvent(Event.ready);
//
        onMessageEvent(Event.vb);
        onMessageEvent(Event.light);
        onMessageEvent(Event.energyDensity);

        onMessageEvent(Event.show);
        onMessageEvent(Event.length);

        onMessageEvent(Event.energy);
        onMessageEvent(Event.p2);

        onMessageEvent(Event.loading);
        onMessageEvent(Event.tip);
        onMessageEvent(Event.connect);

        WorkParam param = App.getApp().getWorkParam();
        if (param != null) {
            boolean change = false;
            App.getApp().setWorkParam(null);
            if (Event.vb.is532()) {
                if (!VbEvent.is532(param.wave)) {
                    change = true;
                    Command.setWave(false);
                }
            } else {
                if (VbEvent.is532(param.wave)) {
                    change = true;
                    Command.setWave(true);
                }
            }
            h.postDelayed(() -> {
                Command.setParam(param.energy, param.freq, Event.light.getValue());
            }, change ? 200 : 0);
        }
    }

    private void changeLight(int i) {
        binding.lights.setVisibility(View.GONE);
        binding.on.setSelected(false);
        Command.setParam(Event.energy.getValue(), Event.p2.getValue(), i);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(HandleConnect event) {
        if (Const.is1316()) {
            binding.tip2.setVisibility(event.getValue() == 0 ? View.GONE : View.VISIBLE);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(TipEvent event) {
        String s = event.toString();
        binding.tip.setText(s);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(LoadingEvent event) {
        if (event.getValue() == 1) {
            showLoading();
        } else {
            hideLoading();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(P2Event event) {
        binding.freq.setText(event.getValue() + "");
        binding.seek2.setProgress(event.getValue());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(LightEvent event) {
        for (int i = 0; i < lights.size(); i++) {
            lights.get(i).setSelected(i == event.getValue());
        }
        switch (event.getValue()) {
            case 0:
                binding.lightIcon.setSelected(false);
                binding.on.setText("OFF");
                break;
            default:
                binding.lightIcon.setSelected(true);
                binding.on.setText(Utils.intToRoman(event.getValue()));
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(CountEvent event) {
        String tmp = binding.num.getText().toString().trim();
        binding.num.setText(event.getValue() + "");
        long old;
        try {
            old = Long.valueOf(tmp);
        } catch (Throwable e) {
            return;
        }
        if (Models.Companion.get().getRentEvent().getValue() == 1 && Event.ready.getValue() == 1) {
            long l = Models.Companion.get().getPointEvent().getValue();
            l -= event.getValue() - old;
            Models.Companion.get().getPointEvent().postValue(Math.max(0, l));
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(ConditionState event) {
        binding.simmer.setSelected(event.getValue() == 1);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(LengthEvent event) {
        binding.length.setText(event.getValue() + "mm");
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(ShowLength event) {
        if (event.getValue() == 1) {
            binding.length.setVisibility(View.INVISIBLE);
        } else {
            binding.length.setVisibility(View.VISIBLE);
        }
    }

    Treat treat;
    boolean started = false;
    long startTime, workPoint;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(ReadyState event) {
        binding.work.setSelected(event.getValue() == 1);
        if (event.getValue() == 1) {
            if (started) {
                return;
            }
            workPoint = Event.count.getValue();
            started = true;
            startTime = System.currentTimeMillis();
            if (MyApp.getApp().getDoc() != null) {
                treat = new Treat();
                treat.docId = MyApp.getApp().getDoc().id;
                if (BaseBoardActivity.custom != null) {
                    treat.cusId = BaseBoardActivity.custom.id;
                }
                treat.start = System.currentTimeMillis();
                new TreatDao().insert(treat, new DBListener() {
                    @Override
                    public void onResult(boolean bo, String msg, Object result) {
                        if (bo) {
                            treat = (Treat) result;
                        }
                    }
                });
            }
        } else {
            if (started) {
                if (treat != null && treat.id != -1L && treat.start > 0) {
                    treat.end = System.currentTimeMillis();
                    new TreatDao().updateEnd(treat, null);
                }
                treat = null;
                workPoint = Event.count.getValue() - workPoint;
                if (workPoint > 0 || BuildConfig.DEBUG || Const.jump) {
                    record(workPoint, System.currentTimeMillis() - startTime);
                }
                started = false;
            }
        }
    }

    private void record(long point, long time) {
        if (BaseBoardActivity.custom != null) {
            BaseBoardActivity.custom.num += point;
            new CustomDao().updateCount(BaseBoardActivity.custom, null);
        }
        try {
            insert(point, time);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        if (MyApp.getApp().getDoc() != null) {
            MyApp.getApp().getDoc().num += point;
            new DocDao().updateCount(MyApp.getApp().getDoc(), null);
        }
    }

    CusUsageDao dao;

    protected void insert(long point, long time) {
        Custom usr = BaseBoardActivity.custom;
        if (dao == null) {
            dao = new CusUsageDao();
        }
        WorkParam tmp = buildParam();
        tmp.shot = point;
        Gson gson = new Gson();
        dao.insert(point, usr, 0, gson.toJson(tmp), new DBListener() {
            @Override
            public void onResult(boolean bo, String msg, Object result) {
                if (bo) {
                    new ReportReq(buildReportParam(tmp), usr == null ? "" : usr.serverId, Const.REPORT).req(new ReqCallback<ReportBean>() {
                        @Override
                        public void callback(boolean success, ReportBean bean) {
                            if (success && bean != null && bean.isValid()) {
                                dao.updateFlag((Long) result, null);
                            }
                        }
                    });
                }
            }
        });
    }

    protected WorkParam buildParam() {
        WorkParam param = new WorkParam();
        param.energy = Event.energy.getValue();
        param.freq = Event.p2.getValue();
        param.wave = Event.vb.getValue();
        param.handle = Event.handle.getValue();
        param.red = Event.light.getValue();
        param.length = Event.length.getValue();
        return param;
    }

    protected final Map buildReportParam(WorkParam param) {
        Gson g = Utils.getGson();
        HashMap map = g.fromJson(g.toJson(param), HashMap.class);
        return map;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(EnergyDensity event) {
        binding.density.setText(String.format("%.2fJ/cm²", event.getValue() / 100f));
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(VbEvent event) {
        binding.f0.setSelected(event.is532());
        binding.f1.setSelected(event.is1064());

        binding.f0.setText(event.get532Name());
        binding.f1.setText(event.get1064Name());

        binding.seek1.setMaxValue(Event.energy.getMax());
        binding.seek1.setMinValue(Event.energy.getMin());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(Energy event) {
        binding.energy.setText(event.getValue() + "");
        binding.seek1.setProgress(event.getValue());
    }

    @Override
    public boolean isWorking() {
        return Event.condition.getValue() == 1 || Event.ready.getValue() == 1;
    }

    @Override
    public boolean stopWork() {
        return false;
    }

    @Override
    public void back2Board() {
        Command.sendTouchEvent(0, 0x20);
        super.back2Board();
    }
}
